import serial
import struct
import time
import os
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import CubicSpline
from mpl_toolkits.mplot3d import Axes3D
from scipy.signal import savgol_filter

class SensorDataCollector:
    def __init__(self, port_1,baud_rate_1,command_hex_1, expected_length_1, packet_length_1, file_path_1):
        self.port_1 = port_1  # 端口名称 com1
        self.baud_rate_1 = baud_rate_1
        self.command_1 = bytes.fromhex(command_hex_1)  # 接受一个十六进制字符串作为输入，并将其转换为对应的字节串
        self.expected_length_1 = expected_length_1
        self.packet_length_1 = packet_length_1
        self.file_path_1 = file_path_1
        self.count = 0

        # 检查并创建路径中的目录
        os.makedirs(os.path.dirname(file_path_1), exist_ok=True)
        self._prepare_txt_file_1()

    def _prepare_txt_file_1(self):
        # 如果文件存在，清空文件内容
        open(self.file_path_1, 'w').close()
        print(f"文件 {self.file_path_1} 已创建/清空。")


    def send_command_1(self, ser):
        ser.write(self.command_1)
        print("指令已发送：", self.command_1.hex().upper())


    def receive_data_1(self, ser):
        data_1 = ser.read(self.expected_length_1)
        print("接收到的数据：", data_1.hex().upper())
        return data_1

    def process_data_1(self, data_1):
        float_size = 4  # 分割数据
        sensor_data = []  # 存放转换之后的数据
        num_packets = len(data_1) // self.packet_length_1  # 获取数据包的个数

        for i in range(num_packets):
            start = i * self.packet_length_1  # 计算当前数据位于哪里
            frame = data_1[start:start + self.packet_length_1]  # 开始的位置+数据的长度

            # 按照frame的结构提取指定部分的数据
            binary_data = bytes(frame[5:17] + frame[18:30] + frame[31:43] + frame[44:56])

            # 将数据切片成4字节的块
            slices = [binary_data[i:i + float_size] for i in range(0, len(binary_data), float_size)]

            # 将每个块转换为大端序列
            big_endian_data = [slice[::-1] for slice in slices]  # 倒序输出

            # 将大端序列的每个块转换为浮点数
            float_array = [struct.unpack('>f', slice)[0] for slice in big_endian_data]

            sensor_data.extend(float_array)  # 展平成一维数组

        return sensor_data


    def collect_sensor_data_1(self):
        with serial.Serial(self.port_1, self.baud_rate_1, timeout=1) as ser_1:
            self.send_command_1(ser_1)
            data = self.receive_data_1(ser_1)
            processed_data_1 = self.process_data_1(data)
        return processed_data_1


    def save_to_txt_1(self, data_1):
        with open(self.file_path_1, 'a') as file:
            file.write(' '.join(map(str, data_1))+'\n' )
        print(f"数据已保存至 {self.file_path_1}")
        self.count += 1


    def run(self, interval):
        sensor_data=[]
        new_ay=[]

        while True:  # 持续读取传感器数据
            sensor_data = self.collect_sensor_data_1()

            sensor_data=(sensor_data[0:48])
            print(sensor_data)

            sensor_data_z= [sensor_data[i] for i in range(2, len(sensor_data), 3)]#提取所有手指z方向的数

            if len(sensor_data_z)==16:
                a_1=(sensor_data_z[1]+7250)*1.5
                a_2=(sensor_data_z[2]+6000)*1.5-1000#手指1
                a_3 = (sensor_data_z[4]+7000)/1.2
                a_6 = -(sensor_data_z[10] + 3500)#手指2
                a_5=sensor_data_z[8]+7500#手指3
                a_7 = (sensor_data_z[13] + 7000)/2
                a_8 = (sensor_data_z[15]+5000)/2 #手指4

                new_ay.append(a_1)#原始数据
                new_ay.append(a_2)#原始数据                    
                for i, value in enumerate(sensor_data):
                    print(f"第{i + 1}个数据值的处理结果：{value}")
                # 保存当前数据到TXT
                self.save_to_txt_1(new_ay)
                new_ay.clear()
            else:
                continue

            

# 示例使用
if __name__ == "__main__":
    collector = SensorDataCollector(
        port_1='COM8',
        baud_rate_1=1000000,
        command_hex_1='5A000603035D',
        expected_length_1=348,
        packet_length_1=58,
        file_path_1='E:\\code\\python\\datacollector\\MagneticData.txt',
    )
    collector.run(interval=0.1)



